<template>
  <el-select
    v-model="currValue"
    filterable
    :filter-method="remoteMethod"
    :disabled="disabled"
    :clearable="clearable"
    v-el-select-loadmore:rangeNum="loadMore(max)"
    @visible-change="visibleChange"
    @clear="clear"
    :placeholder="$t('main.PleaseSelect')"
    :style="{width: widthLength}"
    @change="change"
  >
    <el-option
      v-for="option in renderOption.slice(0, max)"
      :key="option[keyValue]"
      :label="option[labelName]"
      :value="option[keyValue]"
    ></el-option>
  </el-select>
</template>

<script>
export default {
  name: "easySelect",
  directives: {
    "el-select-loadmore": {
      bind(el, binding) {
        // 获取element-ui定义好的scroll盒子
        const SELECTWRAP_DOM = el.querySelector(
          ".el-select-dropdown .el-select-dropdown__wrap"
        );
        SELECTWRAP_DOM.addEventListener("scroll", function() {
          /**
           * scrollHeight 获取元素内容高度(只读)
           * scrollTop 获取或者设置元素的偏移值,常用于, 计算滚动条的位置, 当一个元素的容器没有产生垂直方向的滚动条, 那它的scrollTop的值默认为0.
           * clientHeight 读取元素的可见高度(只读)
           * 如果元素滚动到底, 下面等式返回true, 没有则返回false:
           * ele.scrollHeight - ele.scrollTop === ele.clientHeight;
           */
          const condition =
            this.scrollHeight - this.scrollTop <= this.clientHeight;
          if (condition) binding.value();
        });
      }
    }
  },
  props: {
    // v-model 
    value: {
      type: [String, Number],
      default: ""
    },
    // 下拉项名称字符
    labelName: {
      required: true,
      type: String,
      default: ""
    },
    // 下拉项值字符
    keyValue: {
      required: true,
      type: [String, Number],
      default: ""
    },
    // 是否允许选中
    disabled: {
      type: Boolean,
      default: false
    },
    // 是否允许清空
    clearable: {
      type: Boolean,
      default: true
    },
    // 下拉项
    options: {
      type: Array,
      default: () => []
    },
    widthLength:{
      type:String,
      default: "100%"
    }
  },
  data() {
    return {
      max: 20,//最多显示20条
      renderOption: [] // 通过父级传来的下拉项整理子级下拉数据框
    };
  },
  computed: {
    // 通过计算属性 获取v-model传来的value,且当自己选中项value发生变化时动态传回父级
    currValue: {
      get() {
        // console.log(this.value,"sssssfff");
        return this.value || "";
      },
      set(value) {
        this.$emit("input", value);
      }
    }
  },
  watch: {
    value() {
      // this.addValueOptions();
      this.init();
    },
    options: {
      handler(V) {
        this.init();
      },
      immediate: true,
      deep: true
    }
  },
  created() {
    this.init();
  },
  methods: {
    clear() {
      this.renderOption = this.options;
    },
    loadMore() {
      return () => (this.max += 20);
    },
    visibleChange(flag) {
      // console.log(flag, "下拉框显示隐藏");
      if (flag) {
        this.max = 20;
        this.remoteMethod("")
      }
    },
    async init() {
      this.remoteMethod();
      this.addValueOptions();
    },
    // 回显选中项
    addValueOptions() {
      if (this.currValue) {
        // console.log(this.currValue, "v-model");
        let target = this.options.find(item => {
          // 从大option中找到当前条
          return item[this.keyValue] === this.currValue;
        });
        if (target) {
          // 将当前条与小option比对，没有则加入
          if (
            this.renderOption.every(
              item => item[this.keyValue] !== target[this.keyValue]
            )
          ) {
            this.renderOption.unshift(target);
          }
        }
      }
    },
    addFilterOptions(label) {
      // 每次查找输入时，若有精确匹配的条目，保证该条目一定在renderOption内
      let target = this.options.find(item => {
        // 从大option中找到当前条
        return item[this.keyValue] === this.currValue;
      });
      // console.log(target, "选中的值");
      // console.log(this.renderOption, "下拉选项");
      if (target) {
        // 将当前条与小option比对，没有则加入
        this.renderOption.forEach((element, index) => {
          if (element[this.keyValue] == target[this.keyValue]) {
            this.renderOption = this.options.slice(index);
          }
        });
      }
    },
    remoteMethod(query = "") {
      if (query != "") {
        let arr = this.options.filter(item => {
          // console.log(item,"ssssss");
          return (
            item[this.labelName].toLowerCase().indexOf(query.toLowerCase()) > -1
          );
        });
        // console.log(this.arr, "数据初始化");
        if (arr.length > this.max) {
          this.renderOption = arr;
          this.addFilterOptions();
        } else {
          // console.log("没查到");
          this.renderOption = arr;
        }
      } else {
        this.renderOption = this.options;
        this.addFilterOptions();
      }
    },
    change(value) {
      this.$emit("change", value);
    }
  }
};
</script>
